#!/bin/env python
from __future__ import with_statement
__version__ = "0.6"

import os
#import posixpath
import BaseHTTPServer
import threading
import urllib
from urlparse import urlparse

#from oriolus.pith.packets.packet import FullName

class HttpHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    
    def set_packet_list(self, list_name):
        self.packet_list_name = list_name

    def do_QUIT(self):
        """send 200 OK response, and set server.stop to True"""
        self.send_response(200)
        self.end_headers()
        self.server.stop = True

    def do_GET(self):
        print "GET: '%s'" % self.path 
        parse_results = urlparse(self.path)
        
        if parse_results.path == "/get":
            if not (len(parse_results.query) > 0):
                self.send_response(404)
                self.end_headers()
                return
                
            query_params = dict([part.split('=') for part in parse_results.query.split('&')])
            
            packet_name = urllib.unquote(query_params['name'])
            packet_version = urllib.unquote(query_params['version'])
            paket_full_name = packet_name + '-' + packet_version
        
            if (not packet_name) or (not packet_version):
                self.send_error(406)
                self.end_headers()
                return
            
            packet_filename = paket_full_name +  ".zip.ori"
            if not os.path.exists(packet_filename):
                self.send_response(404)
                self.end_headers()
                return
            
            with open(packet_filename, 'rb') as f:
                if f:
                    self.send_response(200)
                    self.end_headers()
                    self.wfile.write(f.read())
        else:
            self.send_response(404)
            self.end_headers()
        
    def do_POST(self):
        print "POST: '%s'" % self.path 
        parse_results = urlparse(self.path)
        query_params = dict([part.split('=') for part in parse_results[4].split('&')])
        
        packet_name = urllib.unquote(query_params['name'])
        packet_version = urllib.unquote(query_params['version'])
        
        if (not packet_name) or (not packet_version):
            self.send_error(406)
            self.end_headers()
            return
        
        try:
            if parse_results.path == "/post":
                length = int(self.headers.getheader('content-length'))
                print "content-length: %s" % length
                self.__post_package(packet_name, packet_version, self.rfile.read(length))
                self.send_response(200)
            elif parse_results.path == "/remove":
                self.__remove_package(packet_name, packet_version)
                self.send_response(200)
            else:
                self.send_error(404)
        except:
            self.send_error(500)
        finally:
            self.send_header("content-type", "text/plain;charset=utf-8")
            #self.send_header("content-length", "2")
            self.end_headers()
            self.wfile.write("Accepted")
            
    def __post_package(self, packet_name, packet_version, packet_content):
        packet_file_name = packet_name + '-' + packet_version + '.new.zip.ori'
               
        with open(packet_file_name, 'wb') as output_file:
            output_file.write(packet_content)
        
        packet_list_name = "packetlist.yaml"
        
        # Add packet list entry:
        with open(packet_list_name, 'a+') as packetlist_file:
            packetlist_file.write("- name: %s\n" % packet_name)
            packetlist_file.write("  urls:\n  - %s\n" % packet_file_name)
            packetlist_file.write("  version: %s\n" % packet_version)

    def __remove_package(self, packet_name, packet_version):          
        packet_file_name = packet_name + '-' + packet_version + '.zip.ori';   
        with open(packet_file_name, 'wb') as output_file:
            output_file.write(self.rfile)
           
       # Remove packet from list:
        #with open(self.packet_list_name, '+wt') as packetlist_file:
         #   packetlist_file.write()
            
            
class StoppableHttpServer(BaseHTTPServer.HTTPServer):
    """http server that reacts to self.stop flag"""

    def serve_forever(self):
        """Handle one request at a time until stopped."""
        self.stop = False
        while not self.stop:
            self.handle_request()

class Runner():
    __port = 8888
    __server = StoppableHttpServer(("", __port), HttpHandler)
    
    def start(self):
        thread = threading.Thread(target=self.__server.serve_forever)
        thread.start()

    def stop(self):
        """send QUIT request to http server running on localhost:<8888>"""
        conn = httplib.HTTPConnection("localhost:%d" % __port)
        conn.request("QUIT", "/")
        conn.getresponse()

if __name__ == "__main__":
    Runner().start()